using System;
using System.Net.Sockets;
using System.IO;
using System.Text;

namespace ThalesHsmComms
{
	public class HsmConnection
	{
		private String ipAddr;
		private int ipPort;
		private bool UseMsgLenHeader{get;set;}
		private int messageHeaderLen = 8;
		private static short messageHeader = 0;

		private TcpClient socket = null;
		private NetworkStream socketStream = null;

		public bool IsConnected{get;set;}

		public HsmConnection()
		{
		}

		public HsmConnection(String ip, int port)
		{
			this.ipAddr = ip;
			this.ipPort = port;
			this.UseMsgLenHeader = true;
			this.Connect();
			
		}	
		
		public HsmConnection(String ip, int port, bool useMsgLen) 
		{
			this.ipAddr = ip;
			this.ipPort = port;
			this.UseMsgLenHeader = useMsgLen;
			try
			{
				this.Connect();
			} 
			catch (Exception ex) 
			{
				throw ex;
			}
			
		}

		public void Connect()
		{
			this.socket = new TcpClient();
			this.socket.Connect(this.ipAddr,this.ipPort);
			// get output stream
			this.socketStream = this.socket.GetStream();
			this.IsConnected = true;
		}
		
		public void disconnect() 
		{
			// close streams
			this.socketStream.Close();			
			// close socket
			this.socket.Close();
			this.IsConnected = false;

		}


		public String SendRecv(byte[] data)
		{
			MemoryStream rawData = new MemoryStream();
			byte[] recvd = null;
			int recvdLen = 0;
			string strRecvd = null;
			
				
			if (this.UseMsgLenHeader)
			{
				//	write the length of the data on the first 2 bytes
				byte[] bLen = HexConverter.FromShort2HexBinary((short) (data.Length + this.messageHeaderLen));
				rawData.Write(bLen,0,bLen.Length);
			}

			//put in the header.
			byte[] tmp = ASCIIEncoding.ASCII.GetBytes(HexConverter.FromShort2HexString((short) 0));
			rawData.Write(tmp,0,tmp.Length);
			tmp = ASCIIEncoding.ASCII.GetBytes(HexConverter.FromShort2HexString(HsmConnection.messageHeader++));
			rawData.Write(tmp,0,tmp.Length);

			//tmp = ASCIIEncoding.ASCII.GetBytes(data);
			rawData.Write(data,0,data.Length);
			
			// send data to hsm
			byte[] dataToSend = rawData.ToArray();
			this.socketStream.Write(dataToSend,0,dataToSend.Length);

			int len1 = this.socketStream.ReadByte();
			int len2 = this.socketStream.ReadByte();

 			recvdLen = ((len1 << 8)) | (len2);
			recvd = new byte[recvdLen];
			recvdLen = this.socketStream.Read(recvd,0,recvd.Length);

			strRecvd= ASCIIEncoding.ASCII.GetString(recvd,0,recvdLen);
			//strRecvd = HexConverter.FromBinary2HexString(recvd, recvdLen);
				
			if (this.UseMsgLenHeader)
				return strRecvd.Substring(this.messageHeaderLen, strRecvd.Length - this.messageHeaderLen);
			else
				return strRecvd;	
			
		}
	
	}
}

